#ifndef _VIDEO_GRAPHICS_H_
#define _VIDEO_GRAPHICS_H_

#include <dpmi.h>
#include <go32.h>
#include <sys\nearptr.h>

#include "utypes.h"

extern int HRES;
extern int VRES;
extern dword_t VIDEO_MEM;
extern byte_t *VGA;

#define MODE_640x480    0x101
#define MODE_800x600    0x103
#define MODE_1024x768   0x105
#define MODE_1280x1024  0x107

#define INPUT_STATUS 0x03da
#define VRETRACE 0x08

#define ALPHA 12

 /** @defgroup VIDEO_GRAPHICS VIDEO_GRAPHICS
 * @{
 *
 * Aqui estão as funções utilizadas para representar os vários elementos gráficos do jogo, bem como ler ficheiros de Bitmap
 */

/**
 * Estrutura de bitmap, usada para imagens.
 */
struct BITMAP {
  word_t width; ///< Largura da imagem
  word_t height; ///< Altura da imagem
  byte_t palette[256 * 3]; ///< Paleta de cores da imagem
  byte_t *data; ///< Dados da imagem
} __attribute__((__packed__));

typedef struct BITMAP BITMAP;

/**
 * Define a altura e largura de um bitmap
 */
void setBitmapDimensions(BITMAP *bmp, int width, int height);

/**
 * Devolve o endereço base da memória de video
 */
dword_t get_video_mem_address(int mode);

/**
 * Entra no modo gráfico. Devolve um apontador para array do video.
 * Devolve um apontador para a base da memória de vídeo.
 */
byte_t *enter_graphics(int mode, __dpmi_meminfo *map);

/**
 * Sai do modo gráfico
 */
void leave_graphics(__dpmi_meminfo map);

/**
 * Altera o valor de um pixel na posição de ecrã x, y.
 */
void set_pixel(int x, int y, int color, byte_t *target);

/**
 * Devolve o valor do pixel na posição de ecrã x, y.
 */
int get_pixel(int x, int y, byte_t *target);

/**
 * Limpa o ecrã, pondo todos os pixeis a uma certa côr.
 */
inline void clear_screen(char color, byte_t *target);

/**
 * Desenha uma linha de x1, y1 até x2, y2
 */
void draw_line(int x1, int y1, int x2, int y2, int color, byte_t *target);

/**
 * Desenha um criculo com centro no ponto x0, y0 de raio radius, de cor color.
 */
void draw_circle(int x0, int y0, int radius, int color, byte_t *target);

/**
 * Desenha um rectângulo com canto superior esquerdo em x1, y1,
 * de largura width, altura height e cor color
 */
void draw_rectangle(int x1, int y1, int height, int width, int color, byte_t *target);

/**
 * Carrega uma imagem de um ficheiro do tipo bmp de nome file
 */
BITMAP load_bmp(char *file, bool_t read_palette);

/**
 * Desenha um bitmap com canto superior esquero na posição x,y do ecrã
 */
void draw_bitmap(BITMAP *bmp, int x, int y, byte_t *target);

/**
 * Desenha um bitmap com centro na posição x, y do ecrã
 */
void draw_c_bitmap(BITMAP *bmp, int x, int y, byte_t *target);

/**
 * Desenha um bitmap com canto superior esquerdo em x, y, ignorando a cor alpha
 */
void draw_t_bitmap(BITMAP *bmp, int x, int y, byte_t alpha, byte_t *target);

/**
 * Desenha um bitmap com centro em x, y, ignorando a cor alpha
 */
void draw_ct_bitmap(BITMAP *bmp, int x, int y, byte_t alpha, byte_t *target);

/**
 * Desenha um caracter c em x1, y1, de cor foregroundColour, e fundo backgroundColour
 */
void drawChar(char c, int x1, int y1, int foregroundColour, int backgroundColour,
				int charScale, byte_t *target, byte_t *table);

/**
 * Desenha uma string str em x1, y1, de cor foregroundColour, e fundo backgroundColour
 */
void drawString(char *str, int x1, int y1, int foregroundColour, int backgroundColour,
				int charScale, byte_t *target, byte_t *table);

/**
 * Desenha um inteiro num em x1, y1, de cor foregroundColour e fundo backgroundColour
 */
void drawInt(int num, int x1, int y1, int foregroundColour, int backgroundColour,
				int charScale, byte_t *target, byte_t *table);        

/**
 * Define a paleta de cores a ser usada pelo programa
 */
void set_palette(byte_t *pallete);

/**
 * Aguarda que o ecrã actualize
 */
void wait_for_retrace();

/** @} End of VIDEO_GRAPHICS */

#endif
